package com.bgds.sys.data.iXCom29d.config;


import com.bgds.sys.data.iXCom29d.gateway.IXCom29dSocketGateway;
import com.bgds.sys.data.iXCom29d.gateway.impl.*;
import com.bgds.sys.data.iXCom29d.gateway.vo.BaoxinGatewayVo;
import com.cisdi.data.sdk.enums.ByteOrder;
import com.cisdi.data.sdk.gateway.netty.SessionFactory;
import com.cisdi.data.sdk.gateway.netty.TcpIoService;
import com.cisdi.data.sdk.gateway.netty.impl.DefaultTcpIoService;
import com.cisdi.data.sdk.vo.GatewayVo;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import java.nio.charset.Charset;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @Description netty 服务端
 * @Author lj
 * @create: 2020-07-22 10:19
 */
@Configuration
public class EchoServerConfig  {
    @Value("${netty.ports}")
    private int[] ports;

    @Value("${netty.ip}")
    private String ip;

    @Value("${netty.thread_size}")
    private int threadSize;

    @Value("${netty.timeout}")
    private int timeout;

    @Value("${netty.keep_alive}")
    private int keepAlive;

    private static Logger logger = LoggerFactory.getLogger(IXCom29dSocketGateway.class);

    private static TcpIoService ioService = null;
    @SuppressWarnings("unused")
    private static SessionFactory sessionFactory = null;

    @PostConstruct
    public void run() {
        String deviceId = "";
        TcpIoService baoXinTcpIoService = new BaoxinTcpIoService();
        SessionFactory factory = new BaoXingSessionFactory(deviceId, Charset.forName("GBK"));
        factory.init(null, null);
        IXCom29dChannelInitializer<BaoXingVo> channelInitializer =
                new IXCom29dChannelInitializer<BaoXingVo>(factory, Charset.forName("GBK"));
        GatewayVo instanceVo = new BaoxinGatewayVo();
        instanceVo.setByteOrder(ByteOrder.BIGENDIAN);
        StringBuilder parameter=new StringBuilder();
        parameter
                .append("{\"listenIp\":\"").append(ip).append("\",")
//                .append("\"listenPort\":\"").append(port).append("\",")
                .append("\"threadSize\":\"").append(threadSize).append("\",")
                .append("\"timeout\":\"").append(timeout).append("\"}");
        logger.info(parameter.toString());
        instanceVo.setParameter(parameter.toString());
        ((BaoxinGatewayVo) instanceVo).setPorts(ports);
        baoXinTcpIoService.init(instanceVo, factory, channelInitializer);
        ioService = baoXinTcpIoService;
        sessionFactory = factory;

        boolean open = ioService.open();

        if(open == true) {
            AtomicBoolean shouldRun = new AtomicBoolean(true);
            AliveCheckTask task = new AliveCheckTask(keepAlive, shouldRun, factory);

            ThreadFactory threadFactory = new ThreadFactoryBuilder()
                    .setNameFormat("宝信29d-alive-check-thread-%d").build();
            ExecutorService singleThreadPool = new ThreadPoolExecutor(1, 1,
                    0L, TimeUnit.MILLISECONDS,
                    new LinkedBlockingQueue<>(1024), threadFactory, new ThreadPoolExecutor.AbortPolicy());

            singleThreadPool.execute(task);
            singleThreadPool.shutdown();

            logger.info("宝信29d网关启动成功,地址：{}:{}", "0.0.0.0", ports);
        }else {
            logger.info("宝信29d网关启动失败");
        }

    }


}
